package com.hsb.generator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;

public class CodeGenerator {
    static private String driver = "com.mysql.cj.jdbc.Driver";
    static private String url = "jdbc:mysql://127.0.0.1:3306/blog";
    static private String userName = "root";
    static private String password = "H8888";

    static private String tableName = "comment"; //表名
    static private String entityName = "Comment"; //实体类名
    static private String packName = "com.hsb"; //包名
    static private String[] fields; //字段名
    static private String[] properties; //属性名
    static private String[] types; //字段对应的java类型

    //获取属性和类型
    static {
        try {
            //加载驱动和建立连接
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url, userName, password);
            //获取表的数据信息
            Statement statement = connection.createStatement();
            String sql = "select * from " + tableName;
            ResultSet resultSet = statement.executeQuery(sql);
            ResultSetMetaData metaData = resultSet.getMetaData();
            int count = metaData.getColumnCount();//获取字段数量
            fields = new String[count];
            properties = new String[count];
            types = new String[count];
            //获取数据表的字段名和类型
            for (int i = 1; i <= count; i++) {
                String columnName = metaData.getColumnName(i);
                String type = metaData.getColumnTypeName(i);
                fields[i - 1] = columnName;
                //以_对字段名进行分割，将分割后的字符串的首字母变为大写字母，再进行字符串合并
                String[] s = columnName.split("_");
                StringBuilder newColumnName = new StringBuilder();
                if (s.length == 1) {
                    newColumnName.append(s[0]);
                } else {
                    for (int j = 1; j < s.length; j++) {
                        newColumnName.append(s[0]).append(s[j].substring(0, 1).toUpperCase()).append(s[j].substring(1));
                    }
                }
                //将字段的类型转为java基本数据类型
                switch (type) {
                    case "INT":
                        type = "Integer";
                        break;
                    case "VARCHAR":
                    case "DATETIME":
                    case "TEXT":
                        type = "String";
                        break;
                    default:
                        System.out.println("没有该字段类型");
                }
                properties[i - 1] = newColumnName.toString();
                types[i - 1] = type;
            }
            //关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成entity实体类代码
     * @return 生成的代码字符串
     */
    public static String createEntity() {
        StringBuilder property = new StringBuilder();
        for (int i = 0; i < properties.length; i++) {
            property.append("   private ").append(types[i]).append(" ").append(properties[i]).append(";\n");
        }
        String content =
                "package " + packName + ".entity;\n" +
                "\n" +
                "import lombok.AllArgsConstructor;\n" +
                "import lombok.Data;\n" +
                "import lombok.NoArgsConstructor;\n" +
                "import java.io.Serializable;\n" +
                "\n" +
                "@Data\n" +
                "@AllArgsConstructor\n" +
                "@NoArgsConstructor\n" +
                "public class " + entityName + " implements Serializable {\n" +
                property +
                "}";
        return content;
    }

    /**
     * 生成dao类代码
     * @return 生成的代码字符串
     */
    public static String createDao() {
        StringBuilder parameter = new StringBuilder();
        StringBuilder insertValues = new StringBuilder();
        StringBuilder updateValues = new StringBuilder();
        int len = fields.length - 2;
        for (int i = 1; i < len; i++) {
            if (i == len - 1) {
                parameter.append(fields[i]);
                insertValues.append("#{").append(properties[i]).append("}");
                updateValues.append(fields[i]).append("=#{").append(properties[i]).append("}");
            } else {
                parameter.append(fields[i]).append(",");
                insertValues.append("#{").append(properties[i]).append("}").append(",");
                updateValues.append(fields[i]).append("=#{").append(properties[i]).append("}").append(",");
            }
        }
        String content =
                "package " + packName + ".dao;\n" +
                "\n" +
                "import " + packName + ".entity." + entityName + ";\n" +
                "import org.apache.ibatis.annotations.*;\n" +
                "import org.springframework.stereotype.Repository;\n" +
                "\n" +
                "import java.util.List;\n" +
                "\n" +
                "@Repository\n" +
                "public interface " + entityName + "Dao {\n" +
                "    //增加一条记录\n" +
                "    @Insert(\"insert into " + tableName + "(" + parameter + ") values(" + insertValues + ")\")\n" +
                "    int insert(" + entityName + " " + tableName + ");\n" +
                "\n" +
                "    //根据id删除记录\n" +
                "    @Delete(\"delete from " + tableName + " where " + fields[0] + "=#{" + properties[0] + "}\")\n" +
                "    int deleteById(int id);\n" +
                "\n" +
                "    //根据id查询记录\n" +
                "    @Select(\"select * from " + tableName + " where " + fields[0] + "=#{" + properties[0] + "}\")\n" +
                "    " + entityName + " queryById(int id);\n" +
                "\n" +
                "    //查询所有记录\n" +
                "    @Select(\"select * from " + tableName + "\")\n" +
                "    List<" + entityName + "> queryAll();\n" +
                "\n" +
                "    //根据id修改记录\n" +
                "    @Update(\"update " + tableName + " set " + updateValues + " where " + fields[0] + "=#{" + properties[0] + "}\")\n" +
                "    int updateById(" + entityName + " " + tableName + ");\n" +
                "}";
        return content;
    }

    /**
     * 生成service类代码
     * @return 生成的代码字符串
     */
    public static String createService() {
        String content =
                "package " + packName + ".service;\n" +
                "\n" +
                "import " + packName + ".entity." + entityName + ";\n" +
                "\n" +
                "import java.util.List;\n" +
                "\n" +
                "public interface " + entityName + "Service {\n" +
                "    //增加一条记录\n" +
                "    int insert(" + entityName + " " + tableName + ");\n" +
                "\n" +
                "    //根据id删除记录\n" +
                "    int deleteById(int id);\n" +
                "\n" +
                "    //根据id查询记录\n" +
                "    " + entityName + " queryById(int id);\n" +
                "\n" +
                "    //查询所有记录\n" +
                "    List<" + entityName + "> queryAll();\n" +
                "\n" +
                "    //根据id修改记录\n" +
                "    int updateById(" + entityName + " " + tableName + ");\n" +
                "}";
        return content;
    }

    /**
     * 生成serviceImpl类代码
     * @return 生成的代码字符串
     */
    public static String createServiceImpl() {
        String content =
                "package " + packName + ".service.impl;\n" +
                "\n" +
                "import " + packName + ".dao." + entityName + "Dao;\n" +
                "import " + packName + ".entity." + entityName + ";\n" +
                "import " + packName + ".service." + entityName + "Service;\n" +
                "import org.springframework.beans.factory.annotation.Autowired;\n" +
                "import org.springframework.stereotype.Service;\n" +
                "\n" +
                "import java.util.List;\n" +
                "\n" +
                "@Service\n" +
                "public class " + entityName + "ServiceImpl implements " + entityName + "Service {\n" +
                "    @Autowired\n" +
                "    private " + entityName + "Dao " + tableName + "Dao;\n" +
                "\n" +
                "    @Override\n" +
                "    public int insert(" + entityName + " " + tableName + ") {\n" +
                "        return " + tableName + "Dao.insert(" + tableName + ");\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public int deleteById(int id) {\n" +
                "        return " + tableName + "Dao.deleteById(id);\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public " + entityName + " queryById(int id) {\n" +
                "        return " + tableName + "Dao.queryById(id);\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public List<" + entityName + "> queryAll() {\n" +
                "        return " + tableName + "Dao.queryAll();\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public int updateById(" + entityName + " " + tableName + ") {\n" +
                "        return " + tableName + "Dao.updateById(" + tableName + ");\n" +
                "    }\n" +
                "}";
        return content;
    }

    /**
     * 生成controller类代码
     * @return 生成的代码字符串
     */
    public static String createController() {
        StringBuilder insertParamMapper = new StringBuilder();
        StringBuilder insertParam = new StringBuilder();
        StringBuilder iparam = new StringBuilder();
        int len = properties.length - 2;

        for (int i = 0; i < len; i++) {
            if (i == len - 1) {
                insertParamMapper.append("{").append(properties[i]).append("}");
                insertParam.append("@PathVariable(\"").append(properties[i]).append("\") ").append(types[i]).append(" ").append(properties[i]);
                iparam.append(properties[i]);
            } else {
                if (i != 0) {
                    insertParamMapper.append("{").append(properties[i]).append("}").append("/");
                    insertParam.append("@PathVariable(\"").append(properties[i]).append("\") ").append(types[i]).append(" ").append(properties[i]).append(",");
                    iparam.append(properties[i]).append(",");
                }
            }
        }
        String content =
                "package " + packName + ".controller;\n" +
                "\n" +
                "import " + packName + ".entity." + entityName + ";\n" +
                "import " + packName + ".service." + entityName + "Service;\n" +
                "import org.springframework.beans.factory.annotation.Autowired;\n" +
                "import org.springframework.web.bind.annotation.*;\n" +
                "\n" +
                "import java.util.List;\n" +
                "\n" +
                "@RestController\n" +
                "@RequestMapping(\"/" + tableName + "\")\n" +
                "public class " + entityName + "Controller {\n" +
                "    @Autowired\n" +
                "    private " + entityName + "Service " + tableName + "Service;\n" +
                "\n" +
                "    //增加一条记录\n" +
                "    @PostMapping(\"/insert/" + insertParamMapper + "\")\n" +
                "    public Boolean insert(" + insertParam + ") {\n" +
                "        int i = " + tableName + "Service.insert(new " + entityName + "(" + iparam + "));\n" +
                "        return i > 0;\n" +
                "    }\n" +
                "\n" +
                "    //根据id删除记录\n" +
                "    @DeleteMapping(\"/delete/{id}\")\n" +
                "    public Boolean deleteById(@PathVariable Integer id) {\n" +
                "        int i = " + tableName + "Service.deleteById(id);\n" +
                "        return i > 0;\n" +
                "    }\n" +
                "\n" +
                "    //根据id查询记录\n" +
                "    @GetMapping(\"/query/{id}\")\n" +
                "    public " + entityName + " queryById(@PathVariable Integer id) {\n" +
                "        return " + tableName + "Service.queryById(id);\n" +
                "    }\n" +
                "\n" +
                "    //查询所有记录\n" +
                "    @GetMapping(\"/queryAll\")\n" +
                "    public List<" + entityName + "> queryAll() {\n" +
                "        return " + tableName + "Service.queryAll();\n" +
                "    }\n" +
                "\n" +
                "    //根据id修改记录\n" +
                "    @PutMapping(\"/update/{id}/" + insertParamMapper + "\")\n" +
                "    public Boolean update(@PathVariable(\"id\") Integer id," + insertParam + ") {\n" +
                "        int i = " + tableName + "Service.updateById(new " + entityName + "(id," + iparam + "));\n" +
                "        return i > 0;\n" +
                "    }\n" +
                "}";
        return content;
    }

    /**
     * 自动生成代码
     */
    public static void autoCreateCodeToFile() {
        //获取当前项目路径
        String urlPath = System.getProperty("user.dir");
        //将包名转为路径
        String s = packName.replaceAll("\\.", "\\\\");
        //文件路径
        String entityPath = urlPath + "\\src\\main\\java\\"+s+"\\entity\\" + entityName + ".java";
        String daoPath = urlPath + "\\src\\main\\java\\"+s+"\\dao\\" + entityName + "Dao.java";
        String servicePath = urlPath + "\\src\\main\\java\\"+s+"\\service\\" + entityName + "Service.java";
        String serviceImplPath = urlPath + "\\src\\main\\java\\"+s+"\\service\\impl\\" + entityName + "ServiceImpl.java";
        String controllerPath = urlPath + "\\src\\main\\java\\"+s+"\\controller\\" + entityName + "Controller.java";
        //创建文件
        createFile(entityPath, createEntity());
        createFile(daoPath, createDao());
        createFile(servicePath, createService());
        createFile(serviceImplPath, createServiceImpl());
        createFile(controllerPath, createController());
    }

    private static void createFile(String filePath, String content) {
        File file = new File(filePath);
        //获取父文件路径
        File parent = file.getParentFile();
        //判断文件路径是否存在，不存在则创建目录
        if (!parent.exists()) {
            parent.mkdirs();
        }
        try {
            //创建文件
            file.createNewFile();
            //将生成代码写入文件中
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(content);
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件创建失败");
        }
    }
}
